UNPKG

@polygonjs/polygonjs

Version:

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

166 lines (165 loc) 5.09 kB
"use strict"; import { TypedCopNode } from "./_Base"; import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig"; import { CubeReflectionMapping, CubeRefractionMapping } from "three"; import { CopType } from "../../poly/registers/nodes/types/Cop"; import { isBooleanTrue } from "../../../core/Type"; import { CopRendererController } from "./utils/RendererController"; var MapMode = /* @__PURE__ */ ((MapMode2) => { MapMode2["REFLECTION"] = "reflection"; MapMode2["REFRACTION"] = "refraction"; return MapMode2; })(MapMode || {}); const MAP_MODES = ["reflection" /* REFLECTION */, "refraction" /* REFRACTION */]; class CubeCameraCopParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); /** @param cube camera OBJ node */ this.cameraPath = ParamConfig.STRING("*cubeCamera*", { objectMask: true }); /** @param objects to render */ // objects = ParamConfig.STRING('/', { // objectMask: true, // }); /** @param defines if the texture is used for reflection or refraction */ this.mode = ParamConfig.INTEGER(0, { menu: { entries: MAP_MODES.map((name, value) => { return { name, value }; }) } }); /** @param transparent background */ this.transparentBackground = ParamConfig.BOOLEAN(1); /** @param bg Color */ this.backgroundColor = ParamConfig.COLOR([0, 0, 0], { visibleIf: { transparentBackground: 0 } }); /** @param autoRender */ this.autoRender = ParamConfig.BOOLEAN(1); /** @param render button */ this.render = ParamConfig.BUTTON(null, { callback: (node) => { CubeCameraCopNode.PARAM_CALLBACK_render(node); } }); } } const ParamsConfig = new CubeCameraCopParamsConfig(); export class CubeCameraCopNode extends TypedCopNode { constructor() { super(...arguments); this.paramsConfig = ParamsConfig; // private previousParentByObject: WeakMap<Object3D, Object3D | null> = new WeakMap(); this._renderOnTargetBound = () => this.renderOnTarget(true); } static type() { return CopType.CUBE_CAMERA; } async cook() { if (isBooleanTrue(this.pv.autoRender)) { this._addOnBeforeTickCallback(); } else { this._removeOnBeforeTickCallback(); } const texture = await this.renderOnTarget(false); if (texture) { const mode = MAP_MODES[this.pv.mode]; switch (mode) { case "reflection" /* REFLECTION */: texture.mapping = CubeReflectionMapping; break; case "refraction" /* REFRACTION */: texture.mapping = CubeRefractionMapping; break; } } else { this.cookController.endCook(); } } // // // AUTO RENDER // // _addOnBeforeTickCallback() { const callbackName = this._onBeforeRenderCallbackName(); if (this.scene().hasBeforeTickCallback(callbackName)) { return; } this.scene().registerOnBeforeTick(callbackName, this._renderOnTargetBound); } _removeOnBeforeTickCallback() { this.scene().unRegisterOnBeforeTick(this._onBeforeRenderCallbackName()); } _onBeforeRenderCallbackName() { return `cop/render_onBeforeTickCallback-${this.graphNodeId()}`; } dispose() { super.dispose(); this._removeOnBeforeTickCallback(); } // // // RENDER + RENDER TARGET // // _getCameraSync() { return this.scene().objectsController.findObjectByMask(this.pv.cameraPath); } async _getCamera() { const camera = this._getCameraSync(); if (camera) { return camera; } return new Promise((resolve) => { this.scene().camerasController.onCameraObjectsUpdated(async () => { const camera2 = this._getCameraSync(); if (camera2) { resolve(camera2); } }); }); } async renderOnTarget(setDirtyIfChangesDetected) { const camera = await this._getCamera(); if (!camera) { console.warn(`${this.path()}: no camera found`); return; } this._rendererController = this._rendererController || new CopRendererController(this); const renderer = await this._rendererController.waitForRenderer(); if (!renderer) { return; } if (setDirtyIfChangesDetected == true && this._prevCamera != camera || renderer != this._prevRenderer) { this.setDirty(); this._prevCamera = camera; this._prevRenderer = renderer; } const scene = this.scene().threejsScene(); const prevBackground = scene.background; scene.background = this.pv.transparentBackground ? null : this.pv.backgroundColor; camera.update(renderer, scene); scene.background = prevBackground; const texture = camera.renderTarget.texture; this.setTexture(texture); return texture; } // private _renderTarget: WebGLRenderTarget | undefined; async renderTarget() { const camera = await this._getCamera(); return camera == null ? void 0 : camera.renderTarget.texture; } // // // CALLBACK // // static PARAM_CALLBACK_render(node) { node.renderOnTarget(true); } }