polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
207 lines (190 loc) • 8.1 kB
text/typescript
import {GlobalsBaseController} from './_Base';
import {GlobalsGlNode} from '../../Globals';
import {AttributeGlNode} from '../../Attribute';
// import {Definition} from '../../Definition/_Module';
// import {DefinitionBaseConfig} from '../Config/DefinitionBaseConfig';
// import {BaseGlNodeType} from '../../_Base';
import {VaryingGLDefinition, AttributeGLDefinition} from '../../utils/GLDefinition';
import {GlConnectionPointType} from '../../../utils/io/connections/Gl';
// import {TypeAssert} from '../../../../poly/Assert';
import {MapUtils} from '../../../../../core/MapUtils';
import {ShaderName} from '../../../utils/shaders/ShaderName';
import {BaseGlNodeType} from '../../_Base';
import {ShadersCollectionController} from '../utils/ShadersCollectionController';
import {PolyDictionary} from '../../../../../types/GlobalTypes';
const VARIABLE_CONFIG_DEFAULT_BY_NAME: PolyDictionary<string> = {
position: 'vec3( position )',
};
export class GlobalsGeometryHandler extends GlobalsBaseController {
static PRE_DEFINED_ATTRIBUTES = [
'position',
'color',
'normal',
'uv',
'uv2',
'morphTarget0',
'morphTarget1',
'morphTarget2',
'morphTarget3',
'skinIndex',
'skinWeight',
];
static IF_RULE = {
uv:
'defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )',
};
handle_globals_node(
globals_node: GlobalsGlNode,
output_name: string,
shaders_collection_controller: ShadersCollectionController
// definitions_by_shader_name: Map<ShaderName, BaseGLDefinition[]>,
// body_lines_by_shader_name: Map<ShaderName, string[]>,
// body_lines: string[],
// dependencies: ShaderName[],
// shader_name: ShaderName
): void {
const connection_point = globals_node.io.outputs.named_output_connection_points_by_name(output_name);
if (!connection_point) {
return;
}
const var_name = globals_node.gl_var_name(output_name);
const gl_type = connection_point.type();
const definition = new VaryingGLDefinition(globals_node, gl_type, var_name);
// MapUtils.push_on_array_at_entry(definitions_by_shader_name, shader_name, definition);
shaders_collection_controller.add_definitions(globals_node, [definition]);
// definitions_by_shader_name.get(shader_name)!.push(definition);
const assembler = globals_node.material_node?.assemblerController?.assembler;
if (!assembler) {
return;
}
const shader_config = assembler.shader_config(shaders_collection_controller.current_shader_name);
if (!shader_config) {
return;
}
const dependencies = shader_config.dependencies();
const body_line = `${var_name} = ${gl_type}(${output_name})`;
for (let dependency of dependencies) {
// MapUtils.push_on_array_at_entry(definitions_by_shader_name, dependency, definition);
// MapUtils.push_on_array_at_entry(body_lines_by_shader_name, dependency, body_line);
shaders_collection_controller.add_definitions(globals_node, [definition], dependency);
shaders_collection_controller.add_body_lines(globals_node, [body_line], dependency);
}
if (dependencies.length == 0) {
// body_lines.push(body_line);
shaders_collection_controller.add_body_lines(globals_node, [body_line]);
}
}
static variable_config_default(variable_name: string): string | undefined {
return VARIABLE_CONFIG_DEFAULT_BY_NAME[variable_name];
}
variable_config_default(variable_name: string): string | undefined {
return GlobalsGeometryHandler.variable_config_default(variable_name);
}
// variable_config_required_definitions(variable_name:string):DefinitionBaseConfig[]{
// return null
// }
read_attribute(
node: BaseGlNodeType,
gl_type: GlConnectionPointType,
attrib_name: string,
shaders_collection_controller: ShadersCollectionController
) {
return GlobalsGeometryHandler.read_attribute(node, gl_type, attrib_name, shaders_collection_controller);
}
static read_attribute(
node: BaseGlNodeType,
gl_type: GlConnectionPointType,
attrib_name: string,
shaders_collection_controller: ShadersCollectionController
): string | undefined {
if (GlobalsGeometryHandler.PRE_DEFINED_ATTRIBUTES.indexOf(attrib_name) < 0) {
shaders_collection_controller.add_definitions(
node,
[new AttributeGLDefinition(node, gl_type, attrib_name)],
ShaderName.VERTEX
);
} else {
// const if_rule = GlobalsGeometryHandler.IF_RULE[attrib_name]
// if(if_rule){
// const definition = new Definition.Attribute(node, gl_type, attrib_name)
// definition.set_if_rule(if_rule)
// node.add_definitions([definition])
// }
}
// if (!shader_name) {
// throw 'no shader name';
// }
const shader_name = shaders_collection_controller.current_shader_name;
switch (shader_name) {
case ShaderName.VERTEX: {
return attrib_name;
}
case ShaderName.FRAGMENT: {
// let's assume it can only be an attribute gl node
if (!(node instanceof AttributeGlNode)) {
return;
}
const var_name = 'varying_' + node.gl_var_name(node.output_name);
const varying_definition = new VaryingGLDefinition(node, gl_type, var_name);
const definitions_by_shader_name: Map<ShaderName, VaryingGLDefinition[]> = new Map();
// definitions_by_shader_name.set(ShaderName.VERTEX, [])
definitions_by_shader_name.set(ShaderName.FRAGMENT, []);
// {
// [ShaderName.VERTEX]: [],
// [ShaderName.FRAGMENT]: [],
// };
const body_lines_by_shader_name: Map<ShaderName, string[]> = new Map();
// body_lines_by_shader_name.set(ShaderName.VERTEX, [])
body_lines_by_shader_name.set(ShaderName.FRAGMENT, []);
MapUtils.push_on_array_at_entry(definitions_by_shader_name, shader_name, varying_definition);
const set_varying_body_line = `${var_name} = ${gl_type}(${attrib_name})`;
const shader_config = node.material_node?.assemblerController?.assembler.shader_config(shader_name);
if (shader_config) {
const dependencies = shader_config.dependencies();
for (let dependency of dependencies) {
MapUtils.push_on_array_at_entry(definitions_by_shader_name, dependency, varying_definition);
MapUtils.push_on_array_at_entry(body_lines_by_shader_name, dependency, set_varying_body_line);
}
definitions_by_shader_name.forEach((definitions, shader_name) => {
shaders_collection_controller.add_definitions(node, definitions, shader_name);
});
body_lines_by_shader_name.forEach((body_lines, shader_name) => {
shaders_collection_controller.add_body_lines(node, body_lines, shader_name);
});
}
return var_name;
}
}
// TypeAssert.unreachable(shader_name);
// const shader_name = node._shader_name // TODO: this is hack
// const varying_definition = new Definition.Varying(node, gl_type, attrib_name)
// const var_name = varying_definition.name()
// definitions_by_shader_name[shader_name].push(varying_definition)
// const shader_config = node.shader_config(shader_name)
// const dependencies = shader_config.dependencies()
// const body_line = `${var_name} = ${gl_type}(${attrib_name})`
// for(let dependency of dependencies){
// definitions_by_shader_name[dependency].push(varying_definition)
// body_lines_by_shader_name[dependency].push(body_line)
// }
// // if(dependencies.length == 0){
// // body_lines.push(body_line)
// node.add_body_lines([body_line])
// // }
// for(let shader_name of Object.keys(definitions_by_shader_name)){
// node.add_definitions(definitions_by_shader_name[shader_name], shader_name)
// }
// for(let shader_name of Object.keys(body_lines_by_shader_name)){
// node.add_body_lines(body_lines_by_shader_name[shader_name], shader_name)
// }
// node.add_body_lines(body_lines)
}
handle_attribute_node(
node: AttributeGlNode,
gl_type: GlConnectionPointType,
attrib_name: string,
shaders_collection_controller: ShadersCollectionController
) {
return GlobalsGeometryHandler.read_attribute(node, gl_type, attrib_name, shaders_collection_controller);
}
}