UNPKG

@polygonjs/polygonjs

Version:

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

215 lines (214 loc) 6.86 kB
"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; } }