polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
103 lines (97 loc) • 3.59 kB
text/typescript
import {Constructor, valueof} from '../../../types/GlobalTypes';
import {TypedMatNode} from './_Base';
import {GlAssemblerController} from '../gl/code/Controller';
import {NodeParamsConfig} from '../utils/params/ParamsConfig';
import {ShaderAssemblerMaterial} from '../gl/code/assemblers/materials/_BaseMaterial';
import {MaterialPersistedConfig} from '../gl/code/assemblers/materials/PersistedConfig';
import {GlNodeChildrenMap} from '../../poly/registers/nodes/Gl';
import {BaseGlNodeType} from '../gl/_Base';
import {ShaderMaterialWithCustomMaterials} from '../../../core/geometry/Material';
import {NodeContext} from '../../poly/NodeContext';
import {ParamsInitData} from '../utils/io/IOController';
export abstract class TypedBuilderMatNode<
A extends ShaderAssemblerMaterial,
K extends NodeParamsConfig
> extends TypedMatNode<ShaderMaterialWithCustomMaterials, K> {
protected _assembler_controller: GlAssemblerController<A> | undefined;
protected _children_controller_context = NodeContext.GL;
readonly persisted_config: MaterialPersistedConfig = new MaterialPersistedConfig(this);
//
//
// MATERIAL
//
//
create_material() {
let material: ShaderMaterialWithCustomMaterials | undefined;
if (this.persisted_config) {
material = this.persisted_config.material();
}
if (!material) {
material = this.assemblerController?.assembler.create_material() as ShaderMaterialWithCustomMaterials;
}
return material;
}
//
//
// ASSEMBLER
//
//
get assemblerController() {
return (this._assembler_controller = this._assembler_controller || this._create_assembler_controller());
}
protected abstract _create_assembler_controller(): GlAssemblerController<A> | undefined;
createNode<S extends keyof GlNodeChildrenMap>(
node_class: S,
params_init_value_overrides?: ParamsInitData
): GlNodeChildrenMap[S];
createNode<K extends valueof<GlNodeChildrenMap>>(
node_class: Constructor<K>,
params_init_value_overrides?: ParamsInitData
): K;
createNode<K extends valueof<GlNodeChildrenMap>>(
node_class: Constructor<K>,
params_init_value_overrides?: ParamsInitData
): K {
return super.createNode(node_class, params_init_value_overrides) as K;
}
children() {
return super.children() as BaseGlNodeType[];
}
nodesByType<K extends keyof GlNodeChildrenMap>(type: K): GlNodeChildrenMap[K][] {
return super.nodesByType(type) as GlNodeChildrenMap[K][];
}
childrenAllowed() {
if (this.assemblerController) {
return super.childrenAllowed();
}
this.scene().markAsReadOnly(this);
return false;
}
//
//
// COMPILATION
//
//
compile_if_required() {
/* if we recompile while in player mode, there will not be any children gl node created.
So any recompilation will be flawed. A quick way to realise this is with a time dependent material.
And while a scene export would not have an assembler and therefore not recompile,
a temporary display of a scene will the whole engine player will have an assembler and will therefore recompile.
UPDATE: the creation of children is not tied to the player mode anymore, only to the presence of the assembler.
*/
// if (Poly.playerMode()) {
// return;
// }
if (this.assemblerController?.compile_required()) {
this._compile();
}
}
protected _compile() {
const assemblerController = this.assemblerController;
if (this.material && assemblerController) {
assemblerController.assembler.compile_material(this.material);
assemblerController.post_compile();
}
}
}
export type BaseBuilderMatNodeType = TypedBuilderMatNode<ShaderAssemblerMaterial, NodeParamsConfig>;