polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
136 lines (135 loc) • 4.46 kB
JavaScript
import {BaseSopOperation} from "./_Base";
import {Group as Group3} from "three/src/objects/Group";
import {InputCloneMode as InputCloneMode2} from "../../../engine/poly/InputCloneMode";
import {TypeAssert} from "../../../engine/poly/Assert";
export var HierarchyMode;
(function(HierarchyMode2) {
HierarchyMode2["ADD_PARENT"] = "add_parent";
HierarchyMode2["REMOVE_PARENT"] = "remove_parent";
HierarchyMode2["ADD_CHILD"] = "add_child";
})(HierarchyMode || (HierarchyMode = {}));
export const HIERARCHY_MODES = [
HierarchyMode.ADD_PARENT,
HierarchyMode.REMOVE_PARENT,
HierarchyMode.ADD_CHILD
];
export class HierarchySopOperation extends BaseSopOperation {
static type() {
return "hierarchy";
}
cook(input_contents, params) {
const core_group = input_contents[0];
const mode = HIERARCHY_MODES[params.mode];
switch (mode) {
case HierarchyMode.ADD_PARENT: {
const objects = this._add_parent_to_core_group(core_group, params);
return this.create_core_group_from_objects(objects);
}
case HierarchyMode.REMOVE_PARENT: {
const objects = this._remove_parent_from_core_group(core_group, params);
return this.create_core_group_from_objects(objects);
}
case HierarchyMode.ADD_CHILD: {
const objects = this._add_child_to_core_group(core_group, input_contents[1], params);
return this.create_core_group_from_objects(objects);
}
}
TypeAssert.unreachable(mode);
}
_add_parent_to_core_group(core_group, params) {
if (params.levels == 0) {
return core_group.objects();
} else {
const new_object = this._add_parent_to_object(core_group.objects(), params);
return [new_object];
}
}
_add_parent_to_object(objects, params) {
let new_parent = new Group3();
new_parent.matrixAutoUpdate = false;
new_parent.add(...objects);
if (params.levels > 0) {
for (let i = 0; i < params.levels - 1; i++) {
new_parent = this._add_new_parent(new_parent, params);
}
}
return new_parent;
}
_add_new_parent(object, params) {
const new_parent2 = new Group3();
new_parent2.matrixAutoUpdate = false;
new_parent2.add(object);
return new_parent2;
}
_remove_parent_from_core_group(core_group, params) {
if (params.levels == 0) {
return core_group.objects();
} else {
const new_objects = [];
for (let object of core_group.objects()) {
const new_children = this._remove_parent_from_object(object, params);
for (let new_child of new_children) {
new_objects.push(new_child);
}
}
return new_objects;
}
}
_remove_parent_from_object(object, params) {
let current_children = object.children;
for (let i = 0; i < params.levels - 1; i++) {
current_children = this._get_children_from_objects(current_children, params);
}
return current_children;
}
_get_children_from_objects(objects, params) {
let object;
const children = [];
while (object = objects.pop()) {
if (object.children) {
for (let child of object.children) {
children.push(child);
}
}
}
return children;
}
_add_child_to_core_group(core_group, child_core_group, params) {
const objects = core_group.objects();
if (!child_core_group) {
this.states?.error.set("input 1 is invalid");
return [];
}
const childObjects = child_core_group.objects();
const mask = params.objectMask.trim();
const maskValid = mask != "";
const parentObjects = maskValid ? this._findObjectsByMaskFromObjects(mask, objects) : objects;
if (params.debugObjectMask) {
console.log(parentObjects);
}
for (let i = 0; i < parentObjects.length; i++) {
const parentObject = parentObjects[i];
const childObject = childObjects[i] || childObjects[0];
if (!childObject) {
this.states?.error.set("no objects found in input 1");
return [];
}
parentObject.add(childObject);
}
return objects;
}
_findObjectsByMaskFromObjects(mask, objects) {
const list = [];
for (let object of objects) {
this.scene.objectsController.objectsByMaskInObject(mask, object, list);
}
return list;
}
}
HierarchySopOperation.DEFAULT_PARAMS = {
mode: 0,
levels: 1,
objectMask: "",
debugObjectMask: false
};
HierarchySopOperation.INPUT_CLONED_STATE = InputCloneMode2.FROM_NODE;