@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
215 lines (214 loc) • 6.86 kB
JavaScript
"use strict";
import { Group } from "three";
import { Poly } from "../../../Poly";
const DISPLAY_PARAM_NAME = "display";
export class ObjChildrenDisplayController {
constructor(node) {
this.node = node;
this._childrenUuids = /* @__PURE__ */ new Set();
this._sopGroup = this._createSopGroup();
this._newSpecializedObjects = [];
this._newObjectsAreDifferent = false;
this._scene = this.node.scene();
}
_createSopGroup() {
const group = new Group();
group.matrixAutoUpdate = false;
return group;
}
sopGroup() {
return this._sopGroup;
}
setSopGroupName() {
this._sopGroup.name = `${this.node.name()}:sopGroup`;
}
dispose() {
this._clearHooks();
}
displayNodeControllerCallbacks() {
return {
onDisplayNodeRemove: () => {
this.removeChildren();
},
onDisplayNodeSet: () => {
setTimeout(() => {
this.requestDisplayNodeContainer();
}, 0);
},
onDisplayNodeUpdate: () => {
if (!this.node.scene().loadingController.loaded()) {
return;
}
this.requestDisplayNodeContainer();
}
};
}
initializeNode() {
var _a;
this.node.object.add(this.sopGroup());
this.node.nameController.add_post_set_fullPath_hook(this.setSopGroupName.bind(this));
this._createSopGroup();
const displayFlag = (_a = this.node.flags) == null ? void 0 : _a.display;
if (displayFlag) {
displayFlag.onUpdate(() => {
this._updateSopGroupHierarchy();
if (displayFlag.active()) {
this.requestDisplayNodeContainer();
}
});
}
}
_updateSopGroupHierarchy() {
var _a;
const displayFlag = (_a = this.node.flags) == null ? void 0 : _a.display;
if (displayFlag) {
const sopGroup = this.sopGroup();
if (this.usedInScene()) {
sopGroup.visible = true;
this.node.object.add(sopGroup);
sopGroup.updateMatrix();
} else {
sopGroup.visible = false;
this.node.object.remove(sopGroup);
}
Poly.onSceneUpdatedHooks.runHooks();
}
}
usedInScene() {
var _a, _b;
const node = this.node;
if (node.disposed() == true) {
return false;
}
const usedInScene = node.usedInScene();
if (!usedInScene) {
return false;
}
const displayFlagOn = ((_b = (_a = node.flags) == null ? void 0 : _a.display) == null ? void 0 : _b.active()) || false;
if (!displayFlagOn) {
return false;
}
const params = node.params;
const hasActiveParam = params.has(DISPLAY_PARAM_NAME);
const isActiveParamOn = node.params.boolean(DISPLAY_PARAM_NAME);
const paramActiveOn = !hasActiveParam || isActiveParamOn;
return paramActiveOn;
}
async requestDisplayNodeContainer() {
if (!this._scene.loadingController.loaded()) {
return;
}
if (this.usedInScene()) {
await this._setContentUnderSopGroup();
}
}
removeChildren() {
if (this._sopGroup.children.length == 0) {
return;
}
let child;
Poly.onObjectsAddRemoveHooks.runOnRemoveHooks(this._scene, this._sopGroup);
while (child = this._sopGroup.children[0]) {
this._sopGroup.remove(child);
}
this._childrenUuids.clear();
this._notifyCamerasController();
}
async _setContentUnderSopGroup() {
var _a;
const displayNode = this.node.displayNodeController.displayNode();
if (displayNode && ((_a = displayNode.parent()) == null ? void 0 : _a.graphNodeId()) == this.node.graphNodeId()) {
const container = await displayNode.compute();
const coreGroup = container.coreContent();
if (coreGroup) {
const newObjects = coreGroup.threejsObjects();
const _checkObjectsHaveChanged = () => {
const objectsCountChanged = newObjects.length != this._childrenUuids.size;
if (objectsCountChanged) {
return true;
}
for (const object of newObjects) {
if (!this._childrenUuids.has(object.uuid)) {
return true;
}
}
return false;
};
this._newObjectsAreDifferent = _checkObjectsHaveChanged();
this._newSpecializedObjects.length = 0;
this._addSpecializedObjects(displayNode, coreGroup, this._newSpecializedObjects);
if (this._newObjectsAreDifferent) {
this.removeChildren();
const addObject = (object) => {
this._sopGroup.add(object);
object.updateMatrix();
this._childrenUuids.add(object.uuid);
};
for (const object of newObjects) {
addObject(object);
}
for (const object of this._newSpecializedObjects) {
addObject(object);
}
}
this._notifyCamerasController();
this._runOnSopGroupUpdatedHooks();
if (this._scene.loadingController.loaded()) {
Poly.onObjectsAddRemoveHooks.runOnAddHooks(this._scene, this._sopGroup);
Poly.onSceneUpdatedHooks.runHooks();
}
return;
}
}
this.removeChildren();
this._runOnSopGroupUpdatedHooks();
if (this._scene.loadingController.loaded()) {
Poly.onSceneUpdatedHooks.runHooks();
}
}
_notifyCamerasController() {
this._scene.camerasController.updateFromChangeInObject(this._sopGroup);
}
_addSpecializedObjects(displayNode, coreGroup, newObjects) {
}
registerOnSopGroupUpdated(callbackName, callback) {
this._onSopGroupUpdatedHookNames = this._onSopGroupUpdatedHookNames || [];
this._onSopGroupUpdatedHooks = this._onSopGroupUpdatedHooks || [];
this._onSopGroupUpdatedHookNames.push(callbackName);
this._onSopGroupUpdatedHooks.push(callback);
}
_clearHooks() {
if (!this._onSopGroupUpdatedHookNames || !this._onSopGroupUpdatedHooks) {
return;
}
for (const hookName of this._onSopGroupUpdatedHookNames) {
this.deregisterOnSopGroupUpdated(hookName);
}
}
deregisterOnSopGroupUpdated(callbackName) {
var _a;
if (!this._onSopGroupUpdatedHookNames || !this._onSopGroupUpdatedHooks) {
return;
}
const index = (_a = this._onSopGroupUpdatedHookNames) == null ? void 0 : _a.indexOf(callbackName);
this._onSopGroupUpdatedHookNames.splice(index, 1);
this._onSopGroupUpdatedHooks.splice(index, 1);
if (this._onSopGroupUpdatedHookNames.length == 0) {
this._onSopGroupUpdatedHookNames = void 0;
}
if (this._onSopGroupUpdatedHooks.length == 0) {
this._onSopGroupUpdatedHooks = void 0;
}
}
_runOnSopGroupUpdatedHooks() {
if (this._onSopGroupUpdatedHooks) {
const hooks = [...this._onSopGroupUpdatedHooks];
for (const hook of hooks) {
hook();
}
}
}
onSopGroupUpdatedCallbackNames() {
return this._onSopGroupUpdatedHookNames;
}
}