UNPKG

polygonjs-engine

Version:

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

324 lines (313 loc) 9.56 kB
import {Constructor, PolyDictionary} from '../../../../types/GlobalTypes'; import {TypedCopNode} from '../_Base'; import {Texture} from 'three/src/textures/Texture'; import { UVMapping, CubeReflectionMapping, CubeRefractionMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping, CubeUVReflectionMapping, CubeUVRefractionMapping, ClampToEdgeWrapping, RepeatWrapping, MirroredRepeatWrapping, // UnsignedByteType, // ByteType, // ShortType, // UnsignedShortType, // IntType, // UnsignedIntType, // FloatType, // HalfFloatType, // UnsignedShort4444Type, // UnsignedShort5551Type, // UnsignedShort565Type, // UnsignedInt248Type, // AlphaFormat, // RGBFormat, // RGBAFormat, // LuminanceFormat, // LuminanceAlphaFormat, // RGBEFormat, // DepthFormat, // DepthStencilFormat, // encodings LinearEncoding, sRGBEncoding, GammaEncoding, RGBEEncoding, LogLuvEncoding, RGBM7Encoding, RGBM16Encoding, RGBDEncoding, BasicDepthPacking, RGBADepthPacking, } from 'three/src/constants'; import { MAG_FILTER_DEFAULT_VALUE, MAG_FILTER_MENU_ENTRIES, MIN_FILTER_DEFAULT_VALUE, MIN_FILTER_MENU_ENTRIES, } from '../../../../core/cop/ConstantFilter'; const MAPPINGS = [ {UVMapping}, {CubeReflectionMapping}, {CubeRefractionMapping}, {EquirectangularReflectionMapping}, {EquirectangularRefractionMapping}, {CubeUVReflectionMapping}, {CubeUVRefractionMapping}, ]; const ENCODINGS = [ {LinearEncoding}, {sRGBEncoding}, {GammaEncoding}, {RGBEEncoding}, {LogLuvEncoding}, {RGBM7Encoding}, {RGBM16Encoding}, {RGBDEncoding}, {BasicDepthPacking}, {RGBADepthPacking}, ]; const WRAPPINGS: PolyDictionary<number>[] = [{ClampToEdgeWrapping}, {RepeatWrapping}, {MirroredRepeatWrapping}]; import {NodeParamsConfig, ParamConfig} from '../../utils/params/ParamsConfig'; import {CopRendererController} from './RendererController'; import {BaseNodeType} from '../../_Base'; export function TextureParamConfig<TBase extends Constructor>(Base: TBase) { return class Mixin extends Base { /** @param toggle on to allow updating the texture encoding */ tencoding = ParamConfig.BOOLEAN(0); /** @param sets the texture encoding */ encoding = ParamConfig.INTEGER(LinearEncoding, { visibleIf: {tencoding: 1}, menu: { entries: ENCODINGS.map((m) => { return { name: Object.keys(m)[0], value: Object.values(m)[0] as number, }; }), }, }); /** @param toggle on to allow updating the texture mapping */ tmapping = ParamConfig.BOOLEAN(0); /** @param sets the texture mapping */ mapping = ParamConfig.INTEGER(UVMapping, { visibleIf: {tmapping: 1}, menu: { entries: MAPPINGS.map((m) => { return { name: Object.keys(m)[0], value: Object.values(m)[0] as number, }; }), }, }); /** @param toggle on to allow updating the texture wrap */ twrap = ParamConfig.BOOLEAN(0); /** @param sets the texture wrapS */ wrapS = ParamConfig.INTEGER(Object.values(WRAPPINGS[0])[0], { visibleIf: {twrap: 1}, menu: { entries: WRAPPINGS.map((m) => { return { name: Object.keys(m)[0], value: Object.values(m)[0] as number, }; }), }, }); /** @param sets the texture wrapT */ wrapT = ParamConfig.INTEGER(Object.values(WRAPPINGS[0])[0], { visibleIf: {twrap: 1}, menu: { entries: WRAPPINGS.map((m) => { return { name: Object.keys(m)[0], value: Object.values(m)[0] as number, }; }), }, }); wrapSep = ParamConfig.SEPARATOR(null, { visibleIf: {twrap: 1}, }); /** @param toggle on to allow updating the texture min filter */ tminfilter = ParamConfig.BOOLEAN(0); /** @param sets the texture min filter */ minFilter = ParamConfig.INTEGER(MIN_FILTER_DEFAULT_VALUE, { visibleIf: {tminfilter: 1}, menu: { entries: MIN_FILTER_MENU_ENTRIES, }, }); /** @param toggle on to allow updating the texture mag filter */ tmagfilter = ParamConfig.BOOLEAN(0); /** @param sets the texture mag filter */ magFilter = ParamConfig.INTEGER(MAG_FILTER_DEFAULT_VALUE, { visibleIf: {tmagfilter: 1}, menu: { entries: MAG_FILTER_MENU_ENTRIES, }, }); /** @param toggle on to allow updating the texture anisotropy */ tanisotropy = ParamConfig.BOOLEAN(0); /** @param sets the anisotropy from the max value allowed by the renderer */ useRendererMaxAnisotropy = ParamConfig.BOOLEAN(1, { visibleIf: {tanisotropy: 1}, }); /** @param sets the anisotropy manually */ anisotropy = ParamConfig.INTEGER(1, { visibleIf: {tanisotropy: 1, useRendererMaxAnisotropy: 0}, range: [0, 32], rangeLocked: [true, false], }); /** @param TBD */ useCameraRenderer = ParamConfig.BOOLEAN(0, { visibleIf: {tanisotropy: 1, useRendererMaxAnisotropy: 1}, }); anisotropySep = ParamConfig.SEPARATOR(null, { visibleIf: {tanisotropy: 1}, }); /** @param Toggle on to update the flipY */ tflipY = ParamConfig.BOOLEAN(0); /** @param sets the flipY */ flipY = ParamConfig.BOOLEAN(0, {visibleIf: {tflipY: 1}}); /** @param toggle on to update the texture transform */ ttransform = ParamConfig.BOOLEAN(0); /** @param updates the texture offset */ offset = ParamConfig.VECTOR2([0, 0], { visibleIf: {ttransform: 1}, cook: false, callback: (node: BaseNodeType) => { TextureParamsController.PARAM_CALLBACK_update_offset(node as TextureCopNode); }, }); /** @param updates the texture repeat */ repeat = ParamConfig.VECTOR2([1, 1], { visibleIf: {ttransform: 1}, cook: false, callback: (node: BaseNodeType) => { TextureParamsController.PARAM_CALLBACK_update_repeat(node as TextureCopNode); }, }); /** @param updates the texture rotation */ rotation = ParamConfig.FLOAT(0, { range: [-1, 1], visibleIf: {ttransform: 1}, cook: false, callback: (node: BaseNodeType) => { TextureParamsController.PARAM_CALLBACK_update_rotation(node as TextureCopNode); }, }); /** @param updates the texture center */ center = ParamConfig.VECTOR2([0, 0], { visibleIf: {ttransform: 1}, cook: false, callback: (node: BaseNodeType) => { TextureParamsController.PARAM_CALLBACK_update_center(node as TextureCopNode); }, }); }; } class TextureParamsConfig extends TextureParamConfig(NodeParamsConfig) {} const ParamsConfig = new TextureParamsConfig(); class TextureCopNode extends TypedCopNode<TextureParamsConfig> { params_config = ParamsConfig; public readonly texture_params_controller = new TextureParamsController(this); } export class TextureParamsController { constructor(protected node: TextureCopNode) {} update(texture: Texture) { const pv = this.node.pv; if (pv.tencoding) { texture.encoding = pv.encoding; } if (pv.tmapping) { texture.mapping = pv.mapping; } if (pv.twrap) { texture.wrapS = pv.wrapS; texture.wrapT = pv.wrapT; } if (pv.tminfilter) { texture.minFilter = pv.minFilter; } if (pv.tminfilter) { texture.magFilter = pv.magFilter; } this._update_anisotropy(texture); // do not have this in an if block, // as to be sure this is set to false in case it is set to true // by the texture loader texture.flipY = pv.tflipY && pv.flipY; this._update_texture_transform(texture); } private _renderer_controller: CopRendererController | undefined; private async _update_anisotropy(texture: Texture) { const pv = this.node.pv; if (!pv.tanisotropy) { return; } this._renderer_controller = this._renderer_controller || new CopRendererController(this.node); const renderer = await this._renderer_controller.renderer(); const max_anisotropy = renderer.capabilities.getMaxAnisotropy(); if (pv.useRendererMaxAnisotropy) { texture.anisotropy = max_anisotropy; } else { texture.anisotropy = Math.min(pv.anisotropy, max_anisotropy); } } private _update_texture_transform(texture: Texture) { if (!this.node.pv.ttransform) { return; } this._update_offset(texture, false); this._update_repeat(texture, false); this._update_rotation(texture, false); this._update_center(texture, false); texture.updateMatrix(); } private _update_offset(texture: Texture, update_matrix: boolean) { texture.offset.copy(this.node.pv.offset); if (update_matrix) { texture.updateMatrix(); } } private _update_repeat(texture: Texture, update_matrix: boolean) { texture.repeat.copy(this.node.pv.repeat); if (update_matrix) { texture.updateMatrix(); } } private _update_rotation(texture: Texture, update_matrix: boolean) { texture.rotation = this.node.pv.rotation; if (update_matrix) { texture.updateMatrix(); } } private _update_center(texture: Texture, update_matrix: boolean) { texture.center.copy(this.node.pv.center); if (update_matrix) { texture.updateMatrix(); } } static PARAM_CALLBACK_update_offset(node: TextureCopNode) { const texture = node.container_controller.container.texture(); node.texture_params_controller._update_offset(texture, true); } static PARAM_CALLBACK_update_repeat(node: TextureCopNode) { const texture = node.container_controller.container.texture(); node.texture_params_controller._update_repeat(texture, true); } static PARAM_CALLBACK_update_rotation(node: TextureCopNode) { const texture = node.container_controller.container.texture(); node.texture_params_controller._update_rotation(texture, true); } static PARAM_CALLBACK_update_center(node: TextureCopNode) { const texture = node.container_controller.container.texture(); node.texture_params_controller._update_center(texture, true); } }