@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
130 lines (118 loc) • 4.16 kB
text/typescript
/**
* Creates a cube map
*
*
*/
import {Texture, TextureDataType} from 'three';
import {TypedCopNode} from './_Base';
import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig';
import {CopType} from '../../poly/registers/nodes/types/Cop';
import {BaseNodeType} from '../_Base';
import {ParamEvent} from '../../poly/ParamEvent';
import {Poly} from '../../Poly';
import {InputCloneMode} from '../../poly/InputCloneMode';
import {TextureParamConfig, TextureParamsController} from './utils/TextureParamsController';
import {Constructor} from '../../../types/GlobalTypes';
import {CoreCubeTextureLoader} from '../../../core/loader/texture/Cube';
import {EXTENSIONS_BY_NODE_TYPE_BY_CONTEXT} from '../../../core/loader/FileExtensionRegister';
import {NodeContext} from '../../poly/NodeContext';
export enum CubeMapUrlKey {
P = 'p',
N = 'n',
}
// const URL_KEYS:UrlKey[]=[UrlKey.N,UrlKey.P]
export enum CubeMapUrlAxis {
X = 'x',
Y = 'y',
Z = 'z',
}
// const URL_AXISES:UrlAxis[]=[UrlAxis.X,UrlAxis.Y,UrlAxis.Z]
export function cubeMapUrlExpression(urlKey: CubeMapUrlKey, urlAxis: CubeMapUrlAxis) {
return `\`ch('prefix')\`${urlKey}${urlAxis}\`ch('suffix')\``;
}
function CubeMapCopParamConfig<TBase extends Constructor>(Base: TBase) {
return class Mixin extends Base {
/** @param url prefix */
prefix = ParamConfig.STRING('', {
fileBrowse: {
extensions: EXTENSIONS_BY_NODE_TYPE_BY_CONTEXT[NodeContext.COP][CopType.CUBE_MAP],
},
});
/** @param url prefix */
suffix = ParamConfig.STRING('.png');
/** @param reload the image */
reload = ParamConfig.BUTTON(null, {
callback: (node: BaseNodeType) => {
CubeMapCopNode.PARAM_CALLBACK_reload(node as CubeMapCopNode);
},
});
/** @param px url */
px = ParamConfig.STRING(cubeMapUrlExpression(CubeMapUrlKey.P, CubeMapUrlAxis.X));
/** @param nx url */
nx = ParamConfig.STRING(cubeMapUrlExpression(CubeMapUrlKey.N, CubeMapUrlAxis.X));
/** @param py url */
py = ParamConfig.STRING(cubeMapUrlExpression(CubeMapUrlKey.P, CubeMapUrlAxis.Y));
/** @param ny url */
ny = ParamConfig.STRING(cubeMapUrlExpression(CubeMapUrlKey.N, CubeMapUrlAxis.Y));
/** @param pz url */
pz = ParamConfig.STRING(cubeMapUrlExpression(CubeMapUrlKey.P, CubeMapUrlAxis.Z));
/** @param nz url */
nz = ParamConfig.STRING(cubeMapUrlExpression(CubeMapUrlKey.N, CubeMapUrlAxis.Z));
};
}
class CubeMapCopParamsConfig extends TextureParamConfig(CubeMapCopParamConfig(NodeParamsConfig)) {}
const ParamsConfig = new CubeMapCopParamsConfig();
export class CubeMapCopNode extends TypedCopNode<CubeMapCopParamsConfig> {
override paramsConfig = ParamsConfig;
static override type() {
return CopType.CUBE_MAP;
}
public readonly textureParamsController: TextureParamsController = new TextureParamsController(this);
override initializeNode() {
this.io.inputs.setCount(0, 1);
this.io.inputs.initInputsClonedState(InputCloneMode.NEVER);
}
override async cook(inputContents: Texture[]) {
const texture = await this._loadTexture();
if (texture) {
const inputTexture = inputContents[0];
if (inputTexture) {
TextureParamsController.copyTextureAttributes(texture, inputTexture);
}
await this.textureParamsController.update(texture);
this.setTexture(texture);
} else {
this._clearTexture();
}
}
override dispose(): void {
super.dispose();
Poly.blobs.clearBlobsForNode(this);
}
private async _loadTexture() {
const pv = this.pv;
const urls: string[] = [pv.px, pv.nx, pv.py, pv.ny, pv.pz, pv.nz];
let texture: Texture | null = null;
try {
const loader = new CoreCubeTextureLoader(urls, this);
texture = await loader.loadImage({
tdataType: this.pv.ttype && this.pv.tadvanced,
dataType: this.pv.type as TextureDataType,
});
if (texture) {
texture.matrixAutoUpdate = false;
}
} catch (e) {}
if (!texture) {
this.states.error.set(`could not load texture '${urls.join(' ')}'`);
}
return texture;
}
static PARAM_CALLBACK_reload(node: CubeMapCopNode) {
node.paramCallbackReload();
}
private paramCallbackReload() {
this.p.px.setDirty();
this.p.px.emit(ParamEvent.ASSET_RELOAD_REQUEST);
}
}