UNPKG

polygonjs-engine

Version:

node-based webgl 3D engine https://polygonjs.com

102 lines (89 loc) 3.52 kB
import {BaseSopOperation} from './_Base'; import {DefaultOperationParams} from '../_Base'; import {CoreGroup} from '../../geometry/Group'; import {TypedNodePathParamValue} from '../../Walker'; import {GlobalsGeometryHandler} from '../../../engine/nodes/gl/code/globals/Geometry'; import {BufferGeometry} from 'three/src/core/BufferGeometry'; import {ObjectTypeByObject} from '../../geometry/Constant'; import {CoreMaterial} from '../../geometry/Material'; import {NodeContext} from '../../../engine/poly/NodeContext'; import {CoreInstancer} from '../../geometry/Instancer'; import {BaseBuilderMatNodeType} from '../../../engine/nodes/mat/_BaseBuilder'; import {Mesh} from 'three/src/objects/Mesh'; import {Material} from 'three/src/materials/Material'; import {InputCloneMode} from '../../../engine/poly/InputCloneMode'; interface InstanceSopParams extends DefaultOperationParams { attributesToCopy: string; applyMaterial: boolean; material: TypedNodePathParamValue; } export class InstanceSopOperation extends BaseSopOperation { static readonly DEFAULT_PARAMS: InstanceSopParams = { attributesToCopy: 'instance*', applyMaterial: true, material: new TypedNodePathParamValue(''), }; static readonly INPUT_CLONED_STATE = [InputCloneMode.ALWAYS, InputCloneMode.NEVER]; static type(): Readonly<'instance'> { return 'instance'; } private _globals_handler: GlobalsGeometryHandler | undefined; private _geometry: BufferGeometry | undefined; async cook(input_contents: CoreGroup[], params: InstanceSopParams) { const core_group_to_instance = input_contents[0]; this._geometry = undefined; const object_to_instance = core_group_to_instance.objectsWithGeo()[0]; if (object_to_instance) { const geometry_to_instance = object_to_instance.geometry; if (geometry_to_instance) { const core_group = input_contents[1]; this._create_instance(geometry_to_instance, core_group, params); } } if (this._geometry) { const type = ObjectTypeByObject(object_to_instance); if (type) { const object = this.create_object(this._geometry, type); if (params.applyMaterial) { const material = await this._get_material(params); if (material) { await this._applyMaterial(object as Mesh, material); } } return this.create_core_group_from_objects([object]); } } return this.create_core_group_from_objects([]); } private async _get_material(params: InstanceSopParams) { if (params.applyMaterial) { const material_node = params.material.ensure_node_context(NodeContext.MAT, this.states?.error); if (material_node) { this._globals_handler = this._globals_handler || new GlobalsGeometryHandler(); const mat_builder_node = material_node as BaseBuilderMatNodeType; const matNodeAssemblerController = mat_builder_node.assemblerController; if (matNodeAssemblerController) { matNodeAssemblerController.set_assembler_globals_handler(this._globals_handler); } const container = await material_node.requestContainer(); const material = container.material(); return material; } } } async _applyMaterial(object: Mesh, material: Material) { object.material = material; CoreMaterial.apply_custom_materials(object, material); } private _create_instance( geometry_to_instance: BufferGeometry, template_core_group: CoreGroup, params: InstanceSopParams ) { this._geometry = CoreInstancer.create_instance_buffer_geo( geometry_to_instance, template_core_group, params.attributesToCopy ); } }