UNPKG

@polygonjs/polygonjs

Version:

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

165 lines (156 loc) 4.75 kB
/** * Sets the layer of the input objects * * @remarks * This should be combined with the layer of a camera. This will allow some objects to be only visible via some cameras. */ import {TypedSopNode} from './_Base'; import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig'; import {InputCloneMode} from '../../poly/InputCloneMode'; import {CoreGroup} from '../../../core/geometry/Group'; import {SopType} from '../../poly/registers/nodes/types/Sop'; import {filterThreejsObjectsWithGroup} from '../../../core/geometry/Mask'; import {Object3D} from 'three'; export enum LayerUpdateMode { SET = 'set', ADD = 'add', REMOVE = 'remove', } export const UPDATE_MODES: LayerUpdateMode[] = [LayerUpdateMode.SET, LayerUpdateMode.ADD, LayerUpdateMode.REMOVE]; const UPDATE_MODE_ENTRIES = UPDATE_MODES.map((name, value) => { return {name, value}; }); type AvailableLayerIndex = 0 | 1 | 2 | 3; interface VisibleOptions { layersCount: number; } function visibleOption(options: VisibleOptions) { const computedOptions: Record<string, number>[] = []; for (let i = 1; i <= 4; i++) { if (i >= options.layersCount) { computedOptions.push({layersCount: i}); } } return { visibleIf: computedOptions, }; } class LayerSopParamsConfig extends NodeParamsConfig { /** @param group to assign the material to */ group = ParamConfig.STRING('*', { objectMask: true, }); layersCount = ParamConfig.INTEGER(1, { range: [1, 4], rangeLocked: [true, true], separatorAfter: true, }); /** @param updateMode */ updateMode0 = ParamConfig.INTEGER(UPDATE_MODES.indexOf(LayerUpdateMode.ADD), { menu: { entries: UPDATE_MODE_ENTRIES, }, ...visibleOption({layersCount: 1}), }); /** @param layer */ layer0 = ParamConfig.INTEGER(0, { range: [0, 31], rangeLocked: [true, true], ...visibleOption({layersCount: 1}), }); /** @param updateMode */ updateMode1 = ParamConfig.INTEGER(UPDATE_MODES.indexOf(LayerUpdateMode.ADD), { menu: { entries: UPDATE_MODE_ENTRIES, }, ...visibleOption({layersCount: 2}), }); /** @param layer */ layer1 = ParamConfig.INTEGER(0, { range: [0, 31], rangeLocked: [true, true], ...visibleOption({layersCount: 2}), }); /** @param updateMode */ updateMode2 = ParamConfig.INTEGER(UPDATE_MODES.indexOf(LayerUpdateMode.ADD), { menu: { entries: UPDATE_MODE_ENTRIES, }, ...visibleOption({layersCount: 3}), }); /** @param layer */ layer2 = ParamConfig.INTEGER(0, { range: [0, 31], rangeLocked: [true, true], ...visibleOption({layersCount: 3}), }); /** @param updateMode */ updateMode3 = ParamConfig.INTEGER(UPDATE_MODES.indexOf(LayerUpdateMode.ADD), { menu: { entries: UPDATE_MODE_ENTRIES, }, ...visibleOption({layersCount: 4}), }); /** @param layer */ layer3 = ParamConfig.INTEGER(0, { range: [0, 31], rangeLocked: [true, true], ...visibleOption({layersCount: 4}), }); } const ParamsConfig = new LayerSopParamsConfig(); export class LayerSopNode extends TypedSopNode<LayerSopParamsConfig> { override paramsConfig = ParamsConfig; static override type() { return SopType.LAYER; } override initializeNode() { this.io.inputs.setCount(1); this.io.inputs.initInputsClonedState(InputCloneMode.FROM_NODE); } override cook(inputCoreGroups: CoreGroup[]) { const coreGroup = inputCoreGroups[0]; const objects = filterThreejsObjectsWithGroup(coreGroup, this.pv); for (const object of objects) { this._updateLayers(object); // object.layers.set(this.pv.layer); } this.setCoreGroup(coreGroup); } private _updateLayers(object: Object3D) { this._updateLayer(0, object, UPDATE_MODES[this.pv.updateMode0], this.pv.layer0); this._updateLayer(1, object, UPDATE_MODES[this.pv.updateMode1], this.pv.layer1); this._updateLayer(2, object, UPDATE_MODES[this.pv.updateMode2], this.pv.layer2); this._updateLayer(3, object, UPDATE_MODES[this.pv.updateMode3], this.pv.layer3); } private _updateLayer(index: AvailableLayerIndex, object: Object3D, updateMode: LayerUpdateMode, layer: number) { if (index > this.pv.layersCount - 1) { return; } switch (updateMode) { case LayerUpdateMode.SET: { object.layers.set(layer); return; } case LayerUpdateMode.ADD: { object.layers.enable(layer); return; } case LayerUpdateMode.REMOVE: { object.layers.disable(layer); return; } } } // // helper methods // setMode(index: AvailableLayerIndex, mode: LayerUpdateMode) { const param = [this.p.updateMode0, this.p.updateMode1, this.p.updateMode2, this.p.updateMode3]; param[index].set(UPDATE_MODES.indexOf(mode)); } setLayer(index: AvailableLayerIndex, layer: number) { const param = [this.p.layer0, this.p.layer1, this.p.layer2, this.p.layer3]; param[index].set(layer); } }