UNPKG

polygonjs-engine

Version:

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

236 lines (235 loc) 7.14 kB
export const NODE_PATH_DEFAULT = { NODE: { UV: "/COP/imageUv", ENV_MAP: "/COP/envMap" } }; export class TypedNodePathParamValue { constructor(_path = "") { this._path = _path; this._node = null; } set_path(path) { this._path = path; } set_node(node) { this._node = node; } path() { return this._path; } node() { return this._node; } resolve(node_start) { this._node = CoreWalker.find_node(node_start, this._path); } clone() { const cloned = new TypedNodePathParamValue(this._path); cloned.set_node(this._node); return cloned; } ensure_node_context(context, error_state) { const found_node = this.node(); if (!found_node) { error_state?.set(`no node found at ${this.path()}`); return; } const node_context = found_node.nodeContext(); if (node_context == context) { return found_node; } else { error_state?.set(`expected ${context} node, but got a ${node_context}`); return; } } } export class TypedParamPathParamValue { constructor(_path = "") { this._path = _path; this._param = null; } set_path(path) { this._path = path; } set_param(param) { this._param = param; } path() { return this._path; } param() { return this._param; } resolve(node_start) { this._param = CoreWalker.find_param(node_start, this._path); } clone() { const cloned = new TypedParamPathParamValue(this._path); cloned.set_param(this._param); return cloned; } } const CoreWalker2 = class { static split_parent_child(path) { const elements = path.split(CoreWalker2.SEPARATOR).filter((e) => e.length > 0); const child_path = elements.pop(); const parent_path = elements.join(CoreWalker2.SEPARATOR); return {parent: parent_path, child: child_path}; } static find_node(node_src, path, decomposed_path) { if (!node_src) { return null; } const elements = path.split(CoreWalker2.SEPARATOR).filter((e) => e.length > 0); const first_element = elements[0]; let next_node = null; if (path[0] === CoreWalker2.SEPARATOR) { const path_from_root = path.substr(1); next_node = this.find_node(node_src.root(), path_from_root, decomposed_path); } else { switch (first_element) { case CoreWalker2.PARENT: decomposed_path?.add_path_element(first_element); next_node = node_src.parent(); break; case CoreWalker2.CURRENT: decomposed_path?.add_path_element(first_element); next_node = node_src; break; default: next_node = node_src.node(first_element); if (next_node) { decomposed_path?.add_node(first_element, next_node); } } if (next_node != null && elements.length > 1) { const remainder = elements.slice(1).join(CoreWalker2.SEPARATOR); next_node = this.find_node(next_node, remainder, decomposed_path); } return next_node; } return next_node; } static find_param(node_src, path, decomposed_path) { if (!node_src) { return null; } const elements = path.split(CoreWalker2.SEPARATOR); if (elements.length === 1) { return node_src.params.get(elements[0]); } else { const node_path = elements.slice(0, +(elements.length - 2) + 1 || void 0).join(CoreWalker2.SEPARATOR); const node = this.find_node(node_src, node_path, decomposed_path); if (node != null) { const param_name = elements[elements.length - 1]; const param = node.params.get(param_name); if (decomposed_path && param) { decomposed_path.add_node(param_name, param); } return param; } else { return null; } } } static relative_path(src_graph_node, dest_graph_node) { const parent = this.closest_common_parent(src_graph_node, dest_graph_node); if (!parent) { return dest_graph_node.fullPath(); } else { const distance = this.distance_to_parent(src_graph_node, parent); let up = ""; if (distance - 1 > 0) { let i = 0; const ups = []; while (i++ < distance - 1) { ups.push(CoreWalker2.PARENT); } up = ups.join(CoreWalker2.SEPARATOR) + CoreWalker2.SEPARATOR; } const parent_path_elements = parent.fullPath().split(CoreWalker2.SEPARATOR).filter((e) => e.length > 0); const dest_path_elements = dest_graph_node.fullPath().split(CoreWalker2.SEPARATOR).filter((e) => e.length > 0); const remaining_elements = []; let cmptr = 0; for (let dest_path_element of dest_path_elements) { if (!parent_path_elements[cmptr]) { remaining_elements.push(dest_path_element); } cmptr++; } const down = remaining_elements.join(CoreWalker2.SEPARATOR); return `${up}${down}`; } } static closest_common_parent(graph_node1, graph_node2) { const parents1 = this.parents(graph_node1).reverse(); const parents2 = this.parents(graph_node2).reverse(); const min_depth = Math.min(parents1.length, parents2.length); let found_parent = null; for (let i = 0; i < min_depth; i++) { if (parents1[i].graphNodeId() == parents2[i].graphNodeId()) { found_parent = parents1[i]; } } return found_parent; } static parents(graph_node) { const parents = []; let parent = graph_node.parent(); while (parent) { parents.push(parent); parent = parent.parent(); } return parents; } static distance_to_parent(graph_node, dest) { let distance = 0; let current = graph_node; const dest_id = dest.graphNodeId(); while (current && current.graphNodeId() != dest_id) { distance += 1; current = current.parent(); } if (current && current.graphNodeId() == dest_id) { return distance; } else { return -1; } } static make_absolute_path(node_src, path) { if (path[0] == CoreWalker2.SEPARATOR) { return path; } const path_elements = path.split(CoreWalker2.SEPARATOR); const first_element = path_elements.shift(); if (first_element) { switch (first_element) { case "..": { const parent = node_src.parent(); if (parent) { return this.make_absolute_path(parent, path_elements.join(CoreWalker2.SEPARATOR)); } else { return null; } } case ".": { return this.make_absolute_path(node_src, path_elements.join(CoreWalker2.SEPARATOR)); } default: { return [node_src.fullPath(), path].join(CoreWalker2.SEPARATOR); } } } else { return node_src.fullPath(); } } }; export let CoreWalker = CoreWalker2; CoreWalker.SEPARATOR = "/"; CoreWalker.DOT = "."; CoreWalker.CURRENT = CoreWalker2.DOT; CoreWalker.PARENT = ".."; CoreWalker.CURRENT_WITH_SLASH = `${CoreWalker2.CURRENT}/`; CoreWalker.PARENT_WITH_SLASH = `${CoreWalker2.PARENT}/`; CoreWalker.NON_LETTER_PREFIXES = [CoreWalker2.SEPARATOR, CoreWalker2.DOT];