UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

570 lines (524 loc) 18.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.xor = exports.sub = exports.shiftRight = exports.shiftLeft = exports.remainder = exports.or = exports.notEqual = exports.not = exports.mul = exports.modInt = exports.mod = exports.lessThanEqual = exports.lessThan = exports.greaterThanEqual = exports.greaterThan = exports.equal = exports.div = exports.default = exports.bitXor = exports.bitOr = exports.bitNot = exports.bitAnd = exports.and = exports.add = void 0; var _constants = require("../../constants.js"); var _TempNode = _interopRequireDefault(require("../core/TempNode.js")); var _TSLCore = require("../tsl/TSLCore.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * This node represents basic mathematical and logical operations like addition, * subtraction or comparisons (e.g. `equal()`). * * @augments TempNode */ class OperatorNode extends _TempNode.default { static get type() { return 'OperatorNode'; } /** * Constructs a new operator node. * * @param {string} op - The operator. * @param {Node} aNode - The first input. * @param {Node} bNode - The second input. * @param {...Node} params - Additional input parameters. */ 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]; } /** * The operator. * * @type {string} */ this.op = op; /** * The first input. * * @type {Node} */ this.aNode = aNode; /** * The second input. * * @type {Node} */ this.bNode = bNode; /** * This flag can be used for type testing. * * @type {boolean} * @readonly * @default true */ this.isOperatorNode = true; } /** * This method is overwritten since the node type is inferred from the operator * and the input node types. * * @param {NodeBuilder} builder - The current node builder. * @param {string} output - The current output string. * @return {string} The node type. */ getNodeType(builder, output) { 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 === '||' || op === '^^') { return 'bool'; } else if (op === '<' || op === '>' || op === '<=' || op === '>=') { const typeLength = output ? builder.getTypeLength(output) : Math.max(builder.getTypeLength(typeA), builder.getTypeLength(typeB)); return typeLength > 1 ? `bvec${typeLength}` : 'bool'; } else { // Handle matrix operations if (builder.isMatrix(typeA)) { if (typeB === 'float') { return typeA; // matrix * scalar = matrix } else if (builder.isVector(typeB)) { return builder.getVectorFromMatrix(typeA); // matrix * vector } else if (builder.isMatrix(typeB)) { return typeA; // matrix * matrix } } else if (builder.isMatrix(typeB)) { if (typeA === 'float') { return typeB; // scalar * matrix = matrix } else if (builder.isVector(typeA)) { return builder.getVectorFromMatrix(typeB); // vector * matrix } } // Handle non-matrix cases if (builder.getTypeLength(typeB) > builder.getTypeLength(typeA)) { // anytype x anytype: use the greater length vector return typeB; } return typeA; } } generate(builder, output) { const op = this.op; const aNode = this.aNode; const bNode = this.bNode; const type = this.getNodeType(builder, output); 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 === '==' || 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 (op === '%') { typeA = type; typeB = builder.isInteger(typeA) && builder.isInteger(typeB) ? typeB : typeA; } else if (builder.isMatrix(typeA)) { if (typeB === 'float') { // Keep matrix type for typeA, but ensure typeB stays float typeB = 'float'; } else if (builder.isVector(typeB)) { // matrix x vector typeB = builder.getVectorFromMatrix(typeA); } else if (builder.isMatrix(typeB)) { // matrix x matrix - keep both types } else { typeA = typeB = type; } } else if (builder.isMatrix(typeB)) { if (typeA === 'float') { // Keep matrix type for typeB, but ensure typeA stays float typeA = 'float'; } else if (builder.isVector(typeA)) { // vector x matrix typeA = builder.getVectorFromMatrix(typeB); } else { typeA = typeB = type; } } else { // anytype x anytype typeA = typeB = type; } } else { typeA = typeB = type; } const a = aNode.build(builder, typeA); const b = typeof bNode !== 'undefined' ? bNode.build(builder, typeB) : null; const outputLength = builder.getTypeLength(output); const fnOpSnippet = builder.getFunctionOperator(op); if (output !== 'void') { const isGLSL = builder.renderer.coordinateSystem === _constants.WebGLCoordinateSystem; if (op === '==') { if (isGLSL) { if (outputLength > 1) { return builder.format(`${builder.getMethod('equal', output)}( ${a}, ${b} )`, type, output); } else { return builder.format(`( ${a} ${op} ${b} )`, type, output); } } else { // WGSL if (outputLength > 1 || !builder.isVector(typeA)) { return builder.format(`( ${a} == ${b} )`, type, output); } else { return builder.format(`all( ${a} == ${b} )`, type, output); } } } else if (op === '<' && outputLength > 1) { if (isGLSL) { return builder.format(`${builder.getMethod('lessThan', output)}( ${a}, ${b} )`, type, output); } else { // WGSL return builder.format(`( ${a} < ${b} )`, type, output); } } else if (op === '<=' && outputLength > 1) { if (isGLSL) { return builder.format(`${builder.getMethod('lessThanEqual', output)}( ${a}, ${b} )`, type, output); } else { // WGSL return builder.format(`( ${a} <= ${b} )`, type, output); } } else if (op === '>' && outputLength > 1) { if (isGLSL) { return builder.format(`${builder.getMethod('greaterThan', output)}( ${a}, ${b} )`, type, output); } else { // WGSL return builder.format(`( ${a} > ${b} )`, type, output); } } else if (op === '>=' && outputLength > 1) { if (isGLSL) { return builder.format(`${builder.getMethod('greaterThanEqual', output)}( ${a}, ${b} )`, type, output); } else { // WGSL return builder.format(`( ${a} >= ${b} )`, type, output); } } else if (op === '%') { if (builder.isInteger(typeB)) { return builder.format(`( ${a} % ${b} )`, type, output); } else { return builder.format(`${builder.getMethod('mod', type)}( ${a}, ${b} )`, type, output); } } else if (op === '!' || op === '~') { return builder.format(`(${op}${a})`, typeA, output); } else if (fnOpSnippet) { return builder.format(`${fnOpSnippet}( ${a}, ${b} )`, type, output); } else { // Handle matrix operations if (builder.isMatrix(typeA) && typeB === 'float') { return builder.format(`( ${b} ${op} ${a} )`, type, output); } else if (typeA === 'float' && builder.isMatrix(typeB)) { return builder.format(`${a} ${op} ${b}`, type, output); } else { let snippet = `( ${a} ${op} ${b} )`; if (!isGLSL && type === 'bool' && builder.isVector(typeA) && builder.isVector(typeB)) { snippet = `all${snippet}`; } return builder.format(snippet, type, output); } } } else if (typeA !== 'void') { if (fnOpSnippet) { return builder.format(`${fnOpSnippet}( ${a}, ${b} )`, type, output); } else { if (builder.isMatrix(typeA) && typeB === 'float') { return builder.format(`${b} ${op} ${a}`, type, output); } else { return builder.format(`${a} ${op} ${b}`, type, output); } } } } serialize(data) { super.serialize(data); data.op = this.op; } deserialize(data) { super.deserialize(data); this.op = data.op; } } var _default = exports.default = OperatorNode; /** * Returns the addition of two or more value. * * @tsl * @function * @param {Node} a - The first input. * @param {Node} b - The second input. * @param {...Node} params - Additional input parameters. * @returns {OperatorNode} */ const add = exports.add = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '+').setParameterLength(2, Infinity).setName('add'); /** * Returns the subtraction of two or more value. * * @tsl * @function * @param {Node} a - The first input. * @param {Node} b - The second input. * @param {...Node} params - Additional input parameters. * @returns {OperatorNode} */ const sub = exports.sub = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '-').setParameterLength(2, Infinity).setName('sub'); /** * Returns the multiplication of two or more value. * * @tsl * @function * @param {Node} a - The first input. * @param {Node} b - The second input. * @param {...Node} params - Additional input parameters. * @returns {OperatorNode} */ const mul = exports.mul = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '*').setParameterLength(2, Infinity).setName('mul'); /** * Returns the division of two or more value. * * @tsl * @function * @param {Node} a - The first input. * @param {Node} b - The second input. * @param {...Node} params - Additional input parameters. * @returns {OperatorNode} */ const div = exports.div = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '/').setParameterLength(2, Infinity).setName('div'); /** * Computes the remainder of dividing the first node by the second one. * * @tsl * @function * @param {Node} a - The first input. * @param {Node} b - The second input. * @returns {OperatorNode} */ const mod = exports.mod = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '%').setParameterLength(2).setName('mod'); /** * Checks if two nodes are equal. * * @tsl * @function * @param {Node} a - The first input. * @param {Node} b - The second input. * @returns {OperatorNode} */ const equal = exports.equal = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '==').setParameterLength(2).setName('equal'); /** * Checks if two nodes are not equal. * * @tsl * @function * @param {Node} a - The first input. * @param {Node} b - The second input. * @returns {OperatorNode} */ const notEqual = exports.notEqual = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '!=').setParameterLength(2).setName('notEqual'); /** * Checks if the first node is less than the second. * * @tsl * @function * @param {Node} a - The first input. * @param {Node} b - The second input. * @returns {OperatorNode} */ const lessThan = exports.lessThan = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '<').setParameterLength(2).setName('lessThan'); /** * Checks if the first node is greater than the second. * * @tsl * @function * @param {Node} a - The first input. * @param {Node} b - The second input. * @returns {OperatorNode} */ const greaterThan = exports.greaterThan = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '>').setParameterLength(2).setName('greaterThan'); /** * Checks if the first node is less than or equal to the second. * * @tsl * @function * @param {Node} a - The first input. * @param {Node} b - The second input. * @returns {OperatorNode} */ const lessThanEqual = exports.lessThanEqual = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '<=').setParameterLength(2).setName('lessThanEqual'); /** * Checks if the first node is greater than or equal to the second. * * @tsl * @function * @param {Node} a - The first input. * @param {Node} b - The second input. * @returns {OperatorNode} */ const greaterThanEqual = exports.greaterThanEqual = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '>=').setParameterLength(2).setName('greaterThanEqual'); /** * Performs a logical AND operation on multiple nodes. * * @tsl * @function * @param {...Node} nodes - The input nodes to be combined using AND. * @returns {OperatorNode} */ const and = exports.and = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '&&').setParameterLength(2, Infinity).setName('and'); /** * Performs a logical OR operation on multiple nodes. * * @tsl * @function * @param {...Node} nodes - The input nodes to be combined using OR. * @returns {OperatorNode} */ const or = exports.or = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '||').setParameterLength(2, Infinity).setName('or'); /** * Performs logical NOT on a node. * * @tsl * @function * @param {Node} value - The value. * @returns {OperatorNode} */ const not = exports.not = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '!').setParameterLength(1).setName('not'); /** * Performs logical XOR on two nodes. * * @tsl * @function * @param {Node} a - The first input. * @param {Node} b - The second input. * @returns {OperatorNode} */ const xor = exports.xor = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '^^').setParameterLength(2).setName('xor'); /** * Performs bitwise AND on two nodes. * * @tsl * @function * @param {Node} a - The first input. * @param {Node} b - The second input. * @returns {OperatorNode} */ const bitAnd = exports.bitAnd = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '&').setParameterLength(2).setName('bitAnd'); /** * Performs bitwise NOT on a node. * * @tsl * @function * @param {Node} a - The first input. * @param {Node} b - The second input. * @returns {OperatorNode} */ const bitNot = exports.bitNot = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '~').setParameterLength(2).setName('bitNot'); /** * Performs bitwise OR on two nodes. * * @tsl * @function * @param {Node} a - The first input. * @param {Node} b - The second input. * @returns {OperatorNode} */ const bitOr = exports.bitOr = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '|').setParameterLength(2).setName('bitOr'); /** * Performs bitwise XOR on two nodes. * * @tsl * @function * @param {Node} a - The first input. * @param {Node} b - The second input. * @returns {OperatorNode} */ const bitXor = exports.bitXor = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '^').setParameterLength(2).setName('bitXor'); /** * Shifts a node to the left. * * @tsl * @function * @param {Node} a - The node to shift. * @param {Node} b - The value to shift. * @returns {OperatorNode} */ const shiftLeft = exports.shiftLeft = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '<<').setParameterLength(2).setName('shiftLeft'); /** * Shifts a node to the right. * * @tsl * @function * @param {Node} a - The node to shift. * @param {Node} b - The value to shift. * @returns {OperatorNode} */ const shiftRight = exports.shiftRight = /*@__PURE__*/(0, _TSLCore.nodeProxy)(OperatorNode, '>>').setParameterLength(2).setName('shiftRight'); (0, _TSLCore.addMethodChaining)('add', add); (0, _TSLCore.addMethodChaining)('sub', sub); (0, _TSLCore.addMethodChaining)('mul', mul); (0, _TSLCore.addMethodChaining)('div', div); (0, _TSLCore.addMethodChaining)('mod', mod); (0, _TSLCore.addMethodChaining)('equal', equal); (0, _TSLCore.addMethodChaining)('notEqual', notEqual); (0, _TSLCore.addMethodChaining)('lessThan', lessThan); (0, _TSLCore.addMethodChaining)('greaterThan', greaterThan); (0, _TSLCore.addMethodChaining)('lessThanEqual', lessThanEqual); (0, _TSLCore.addMethodChaining)('greaterThanEqual', greaterThanEqual); (0, _TSLCore.addMethodChaining)('and', and); (0, _TSLCore.addMethodChaining)('or', or); (0, _TSLCore.addMethodChaining)('not', not); (0, _TSLCore.addMethodChaining)('xor', xor); (0, _TSLCore.addMethodChaining)('bitAnd', bitAnd); (0, _TSLCore.addMethodChaining)('bitNot', bitNot); (0, _TSLCore.addMethodChaining)('bitOr', bitOr); (0, _TSLCore.addMethodChaining)('bitXor', bitXor); (0, _TSLCore.addMethodChaining)('shiftLeft', shiftLeft); (0, _TSLCore.addMethodChaining)('shiftRight', shiftRight); /** * @tsl * @function * @deprecated since r168. Use {@link mod} instead. * * @param {Node} a - The first input. * @param {Node} b - The second input. * @returns {OperatorNode} */ const remainder = (a, b) => { // @deprecated, r168 console.warn('THREE.TSL: "remainder()" is deprecated. Use "mod( int( ... ) )" instead.'); return mod(a, b); }; /** * @tsl * @function * @deprecated since r175. Use {@link mod} instead. * * @param {Node} a - The first input. * @param {Node} b - The second input. * @returns {OperatorNode} */ exports.remainder = remainder; const modInt = (a, b) => { // @deprecated, r175 console.warn('THREE.TSL: "modInt()" is deprecated. Use "mod( int( ... ) )" instead.'); return mod((0, _TSLCore.int)(a), (0, _TSLCore.int)(b)); }; exports.modInt = modInt; (0, _TSLCore.addMethodChaining)('remainder', remainder); (0, _TSLCore.addMethodChaining)('modInt', modInt);