@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
154 lines (139 loc) • 5.17 kB
text/typescript
import {Constructor, valueof} from '../../../../types/GlobalTypes';
import {TypedNode} from '../../_Base';
import {BaseJsShaderAssembler} from './assemblers/_Base';
import {GlobalsJsBaseController} from './globals/_Base';
import {GlobalsJsGeometryHandler} from './globals/Geometry';
import {OutputJsNode} from '../Output';
import {GlobalsJsNode} from '../Globals';
import {JsNodeChildrenMap} from '../../../poly/registers/nodes/Js';
import {BaseJsNodeType} from '../_Base';
import {JsAssemblerNodeSpareParamsController} from './JsAssemblerNodeSpareParamsController';
import {NodeCreateOptions} from '../../utils/hierarchy/ChildrenController';
class BaseJsParentNode extends TypedNode<any, any> {
override createNode<S extends keyof JsNodeChildrenMap>(
node_class: S,
options?: NodeCreateOptions
): JsNodeChildrenMap[S];
override createNode<K extends valueof<JsNodeChildrenMap>>(
node_class: Constructor<K>,
options?: NodeCreateOptions
): K;
override createNode<K extends valueof<JsNodeChildrenMap>>(
node_class: Constructor<K>,
options?: NodeCreateOptions
): K {
return super.createNode(node_class, options) as K;
}
override children() {
return super.children() as BaseJsNodeType[];
}
override nodesByType<K extends keyof JsNodeChildrenMap>(type: K): JsNodeChildrenMap[K][] {
return super.nodesByType(type) as JsNodeChildrenMap[K][];
}
}
export abstract class AssemblerControllerNode<A extends BaseJsShaderAssembler> extends BaseJsParentNode {
// protected override _childrenControllerContext = NodeContext.JS;
// override createNode<S extends keyof JsNodeChildrenMap>(
// node_class: S,
// options?: NodeCreateOptions
// ): JsNodeChildrenMap[S];
// override createNode<K extends valueof<JsNodeChildrenMap>>(
// node_class: Constructor<K>,
// options?: NodeCreateOptions
// ): K;
// override createNode<K extends valueof<JsNodeChildrenMap>>(
// node_class: Constructor<K>,
// options?: NodeCreateOptions
// ): K {
// return super.createNode(node_class, options) as K;
// }
// override children() {
// return super.children() as BaseJsNodeType[];
// }
// override nodesByType<K extends keyof JsNodeChildrenMap>(type: K): JsNodeChildrenMap[K][] {
// return super.nodesByType(type) as JsNodeChildrenMap[K][];
// }
abstract assemblerController(): JsAssemblerController<A> | undefined;
abstract compile(): void;
}
type BaseJsShaderAssemblerConstructor<A extends BaseJsShaderAssembler> = new (...args: any[]) => A;
export class JsAssemblerController<A extends BaseJsShaderAssembler> {
protected _assembler!: A;
private _spareParamsController!: JsAssemblerNodeSpareParamsController;
private _globalsHandler: GlobalsJsBaseController | undefined = new GlobalsJsGeometryHandler();
private _compileRequired: boolean = true;
constructor(private node: AssemblerControllerNode<A>, assembler_class: BaseJsShaderAssemblerConstructor<A>) {
this._assembler = new assembler_class(this.node);
this._spareParamsController = new JsAssemblerNodeSpareParamsController(this, this.node);
}
setAssemblerGlobalsHandler(globalsHandler: GlobalsJsBaseController) {
const currentType = this._globalsHandler?.type();
const newType = globalsHandler?.type();
if (currentType != newType) {
this._globalsHandler = globalsHandler;
this.setCompilationRequiredAndDirty();
this._assembler.resetConfigs();
}
}
get assembler() {
return this._assembler;
}
globalsHandler() {
return this._globalsHandler;
}
add_output_inputs(output_child: OutputJsNode) {
this._assembler.add_output_inputs(output_child);
}
add_globals_outputs(globals_node: GlobalsJsNode) {
this._assembler.add_globals_outputs(globals_node);
}
allow_attribute_exports() {
return this._assembler.allow_attribute_exports();
}
setCompilationRequired(newState = true) {
this._compileRequired = newState;
}
setCompilationRequiredAndDirty(triggerNode?: BaseJsNodeType) {
if (this.node.scene().loadingController.isLoading()) {
return;
}
this.setCompilationRequired();
if (this._assembler.makeFunctionNodeDirtyOnChange()) {
this.node.setDirty();
} else {
if (this.node.isDirty()) {
// nothing
} else {
this.node.compile();
}
}
// this.setCompilationRequired();
// // if (this._assembler.makeFunctionNodeDirtyOnRecompileRequired()) {
// // this.node.setDirty(triggerNode);
// // } else {
// this.node.compile();
// //}
}
compileRequired(): boolean {
return this._compileRequired;
}
post_compile() {
this.createSpareParameters();
this.setCompilationRequired(false);
}
//
// Create spare params on mat nodes
//
createSpareParameters() {
this._spareParamsController.createSpareParameters();
}
// addFilterFragmentShaderCallback(callbackName: string, callback: (s: string) => string) {
// this.assembler._addFilterFragmentShaderCallback(callbackName, callback);
// this.setCompilationRequired();
// }
// removeFilterFragmentShaderCallback(callbackName: string) {
// this.assembler._removeFilterFragmentShaderCallback(callbackName);
// this.setCompilationRequired();
// }
}
export type JsAssemblerControllerType = JsAssemblerController<BaseJsShaderAssembler>;