@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
269 lines (268 loc) • 8.47 kB
JavaScript
"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];