polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
236 lines (235 loc) • 7.14 kB
JavaScript
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];