UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

269 lines (268 loc) 8.47 kB
"use strict"; export const NODE_PATH_DEFAULT = { NODE: { EMPTY: "", UV: "/COP/imageUv", ENV_MAP: "/COP/envMap", CUBE_MAP: "/COP/cubeCamera" } }; const _remainingElements = []; const _ups = []; class GraphNodePathParamValue { constructor(_path = "") { this._path = _path; this._graphNode = null; } graphNode() { return this._graphNode; } _setGraphNode(graphNode) { this._graphNode = graphNode; } path() { return this._path; } setPath(path) { this._path = path; } clone() { const cloned = new this.constructor(this._path); cloned._setGraphNode(this._graphNode); return cloned; } } export class TypedNodePathParamValue extends GraphNodePathParamValue { setNode(node) { this._graphNode = node; } node() { return this._graphNode; } graphNodePath() { var _a; return (_a = this.node()) == null ? void 0 : _a.path(); } resolve(nodeStart, decomposedPath) { this._graphNode = CoreWalker.findNode(nodeStart, this._path, decomposedPath); } nodeWithContext(context, errorState) { const foundNode = this.node(); if (!foundNode) { errorState == null ? void 0 : errorState.set(`no node found at ${this.path()}`); return; } const nodeContext = foundNode.context(); if (nodeContext == context) { return foundNode; } else { errorState == null ? void 0 : errorState.set(`expected ${context} node, but got a ${nodeContext}`); return; } } } export class TypedParamPathParamValue extends GraphNodePathParamValue { setParam(param) { this._graphNode = param; } param() { return this._graphNode; } graphNodePath() { var _a; return (_a = this.param()) == null ? void 0 : _a.path(); } resolve(nodeStart, decomposedPath) { this._graphNode = CoreWalker.findParam(nodeStart, this._path, decomposedPath); } paramWithType(paramType, error_state) { const foundParam = this.param(); if (!foundParam) { error_state == null ? void 0 : error_state.set(`no param found at ${this.path()}`); return; } if (foundParam.type() == paramType) { return foundParam; } else { error_state == null ? void 0 : error_state.set(`expected ${paramType} node, but got a ${foundParam.type()}`); return; } } } const _CoreWalker = class { static splitParentChild(path) { const elements = path.split(_CoreWalker.SEPARATOR).filter((e) => e.length > 0); const child_path = elements.pop(); const parent_path = elements.join(_CoreWalker.SEPARATOR); return { parent: parent_path, child: child_path }; } static findNode(nodeSrc, path, decomposedPath) { if (!nodeSrc) { return null; } const elements = path.split(_CoreWalker.SEPARATOR).filter((e) => e.length > 0); const firstElement = elements[0]; let nextNode = null; if (path[0] === _CoreWalker.SEPARATOR) { const pathFromRoot = path.substring(1); nextNode = this.findNode(nodeSrc.root(), pathFromRoot, decomposedPath); } else { switch (firstElement) { case _CoreWalker.PARENT: nextNode = nodeSrc.parent(); if (nextNode) { decomposedPath == null ? void 0 : decomposedPath.addPathElement({ path: firstElement, node: nextNode }); } break; case _CoreWalker.CURRENT: nextNode = nodeSrc; decomposedPath == null ? void 0 : decomposedPath.addPathElement({ path: firstElement, node: nextNode }); break; default: nextNode = nodeSrc.node(firstElement); if (nextNode) { decomposedPath == null ? void 0 : decomposedPath.addNamedNode({ name: firstElement, node: nextNode }); } } if (nextNode != null && elements.length > 1) { const remainder = elements.slice(1).join(_CoreWalker.SEPARATOR); nextNode = this.findNode(nextNode, remainder, decomposedPath); } return nextNode; } return nextNode; } static findParam(nodeSrc, path, decomposedPath) { if (!nodeSrc) { return null; } const elements = path.split(_CoreWalker.SEPARATOR); if (elements.length === 1) { return nodeSrc.params.get(elements[0]); } else { let node = null; if (path[0] === _CoreWalker.SEPARATOR && elements.length == 2) { node = nodeSrc.root(); } else { const nodePath = elements.slice(0, +(elements.length - 2) + 1 || void 0).join(_CoreWalker.SEPARATOR); node = this.findNode(nodeSrc, nodePath, decomposedPath); } if (node != null) { const paramName = elements[elements.length - 1]; const param = node.params.get(paramName); if (decomposedPath && param) { decomposedPath.addNamedNode({ name: paramName, node: param }); } return param; } else { return null; } } } static relativePath(srcGraphNode, destGraphNode) { const parent = this.closestCommonParent(srcGraphNode, destGraphNode); if (!parent) { return destGraphNode.path(); } else { const distance = this.distanceToParent(srcGraphNode, parent); let up = ""; if (distance > 0) { let i = 0; _ups.length = 0; while (i++ < distance) { _ups.push(_CoreWalker.PARENT); } up = _ups.join(_CoreWalker.SEPARATOR) + _CoreWalker.SEPARATOR; } const parent_path_elements = parent.path().split(_CoreWalker.SEPARATOR).filter((e) => e.length > 0); const dest_path_elements = destGraphNode.path().split(_CoreWalker.SEPARATOR).filter((e) => e.length > 0); _remainingElements.length = 0; let cmptr = 0; for (const dest_path_element of dest_path_elements) { if (!parent_path_elements[cmptr]) { _remainingElements.push(dest_path_element); } cmptr++; } const down = _remainingElements.join(_CoreWalker.SEPARATOR); return this.sanitizePath(`${up}${down}`); } } static sanitizePath(path) { return path.replace(/\/\//g, "/"); } static closestCommonParent(graphNode1, graphNode2) { const parents1 = this.parents(graphNode1).reverse().concat([graphNode1]); const parents2 = this.parents(graphNode2).reverse().concat([graphNode2]); const minDepth = Math.min(parents1.length, parents2.length); let foundParent = null; for (let i = 0; i < minDepth; i++) { if (parents1[i].graphNodeId() == parents2[i].graphNodeId()) { foundParent = parents1[i]; } } return foundParent; } static parents(graphNode) { const parents = []; let parent = graphNode.parent(); while (parent) { parents.push(parent); parent = parent.parent(); } return parents; } static distanceToParent(graphNode, dest) { let distance = 0; let current = graphNode; const destId = dest.graphNodeId(); while (current && current.graphNodeId() != destId) { distance += 1; current = current.parent(); } if (current && current.graphNodeId() == destId) { return distance; } else { return -1; } } static makeAbsolutePath(nodeSrc, path) { if (path[0] == _CoreWalker.SEPARATOR) { return path; } const pathElements = path.split(_CoreWalker.SEPARATOR); const firstElement = pathElements.shift(); if (firstElement) { switch (firstElement) { case "..": { const parent = nodeSrc.parent(); if (parent) { if (parent == nodeSrc.scene().root()) { return _CoreWalker.SEPARATOR + pathElements.join(_CoreWalker.SEPARATOR); } else { return this.makeAbsolutePath(parent, pathElements.join(_CoreWalker.SEPARATOR)); } } else { return null; } } case ".": { return this.makeAbsolutePath(nodeSrc, pathElements.join(_CoreWalker.SEPARATOR)); } default: { return [nodeSrc.path(), path].join(_CoreWalker.SEPARATOR); } } } else { return nodeSrc.path(); } } }; export let CoreWalker = _CoreWalker; CoreWalker.SEPARATOR = "/"; CoreWalker.DOT = "."; CoreWalker.CURRENT = _CoreWalker.DOT; CoreWalker.PARENT = ".."; CoreWalker.CURRENT_WITH_SLASH = `${_CoreWalker.CURRENT}/`; CoreWalker.PARENT_WITH_SLASH = `${_CoreWalker.PARENT}/`; CoreWalker.NON_LETTER_PREFIXES = [_CoreWalker.SEPARATOR, _CoreWalker.DOT];