@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
131 lines (123 loc) • 4.84 kB
text/typescript
/**
* Creates a constant
*
*
*/
import {TypedGlNode} from './_Base';
import {ThreeToGl} from '../../../core/ThreeToGl';
import {BaseParamType} from '../../params/_Base';
import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig';
import {ShadersCollectionController} from './code/utils/ShadersCollectionController';
import {isNumber, isBooleanTrue} from '../../../core/Type';
import {PolyDictionary} from '../../../types/GlobalTypes';
import {GlConnectionPointType, GL_CONNECTION_POINT_TYPES_FOR_CONSTANT} from '../utils/io/connections/Gl';
import {GlType} from '../../poly/registers/nodes/types/Gl';
function typedVisibleOptions(type: GlConnectionPointType, otherParamVal: PolyDictionary<number | boolean> = {}) {
const val = GL_CONNECTION_POINT_TYPES_FOR_CONSTANT.indexOf(type);
return {visibleIf: {type: val, ...otherParamVal}};
}
class ConstantGlParamsConfig extends NodeParamsConfig {
type = ParamConfig.INTEGER(GL_CONNECTION_POINT_TYPES_FOR_CONSTANT.indexOf(GlConnectionPointType.FLOAT), {
menu: {
entries: GL_CONNECTION_POINT_TYPES_FOR_CONSTANT.map((name, i) => {
return {name: name, value: i};
}),
},
});
bool = ParamConfig.BOOLEAN(0, typedVisibleOptions(GlConnectionPointType.BOOL));
int = ParamConfig.INTEGER(0, typedVisibleOptions(GlConnectionPointType.INT));
float = ParamConfig.FLOAT(0, typedVisibleOptions(GlConnectionPointType.FLOAT));
vec2 = ParamConfig.VECTOR2([0, 0], typedVisibleOptions(GlConnectionPointType.VEC2));
vec3 = ParamConfig.VECTOR3([0, 0, 0], typedVisibleOptions(GlConnectionPointType.VEC3, {asColor: false}));
color = ParamConfig.COLOR([0, 0, 0], typedVisibleOptions(GlConnectionPointType.VEC3, {asColor: true}));
vec4 = ParamConfig.VECTOR4([0, 0, 0, 0], typedVisibleOptions(GlConnectionPointType.VEC4));
/** @param when using vec3, use toggle on it should be a color */
asColor = ParamConfig.BOOLEAN(0, typedVisibleOptions(GlConnectionPointType.VEC3));
}
const ParamsConfig = new ConstantGlParamsConfig();
export class ConstantGlNode extends TypedGlNode<ConstantGlParamsConfig> {
override paramsConfig = ParamsConfig;
static override type() {
return GlType.CONSTANT;
}
static readonly OUTPUT_NAME = 'val';
override initializeNode() {
this.io.connection_points.set_output_name_function((index: number) => ConstantGlNode.OUTPUT_NAME);
this.io.connection_points.set_expected_input_types_function(() => []);
this.io.connection_points.set_expected_output_types_function(() => [this._currentConnectionType()]);
}
override setLines(shaders_collection_controller: ShadersCollectionController) {
const param = this.currentParam();
if (!param) {
console.warn(`no param found for constant node for type '${this.pv.type}'`);
return;
}
const value = this.currentValue();
if (value == null) {
console.warn(`no value found for constant node for type '${this.pv.type}'`);
return;
}
const connection_type = this._currentConnectionType();
const var_value = this._currentVarName();
const body_line = `${connection_type} ${var_value} = ${value}`;
shaders_collection_controller.addBodyLines(this, [body_line]);
}
private _currentConnectionType() {
if (this.pv.type == null) {
console.warn('constant gl node type is null', this.path());
}
const connectionType = GL_CONNECTION_POINT_TYPES_FOR_CONSTANT[this.pv.type] || GlConnectionPointType.FLOAT;
if (connectionType == null) {
console.warn(`constant gl node type if not valid (${this.pv.type})`, this.path());
}
return connectionType;
}
currentParam(): BaseParamType {
const type = GL_CONNECTION_POINT_TYPES_FOR_CONSTANT[this.pv.type];
switch (type) {
case GlConnectionPointType.BOOL: {
return this.p.bool;
}
case GlConnectionPointType.INT: {
return this.p.int;
}
case GlConnectionPointType.FLOAT: {
return this.p.float;
}
case GlConnectionPointType.VEC2: {
return this.p.vec2;
}
case GlConnectionPointType.VEC3: {
if (isBooleanTrue(this.pv.asColor)) {
return this.p.color;
} else {
return this.p.vec3;
}
}
case GlConnectionPointType.VEC4: {
return this.p.vec4;
}
}
// we should never run this
return this.p.bool;
}
private _currentVarName(): string {
return this.glVarName(ConstantGlNode.OUTPUT_NAME);
}
currentValue() {
const param = this.currentParam();
if (param) {
let value = ThreeToGl.any(param.value);
// ensure that it is an integer when needed
// as ThreeToGl.any can only detect if this is a number for now
// and therefore does not make the distinction between float and int
if (param.name() == this.p.int.name() && isNumber(param.value)) {
value = ThreeToGl.integer(param.value);
}
return value;
}
}
setGlType(type: GlConnectionPointType) {
this.p.type.set(GL_CONNECTION_POINT_TYPES_FOR_CONSTANT.indexOf(type));
}
}