UNPKG

polygonjs-engine

Version:

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

103 lines (86 loc) 3.1 kB
/** * blends 2 geometries together. * * @remarks * Note that both geometries must have the same number of points for predictable results * */ import {TypedSopNode} from './_Base'; import {Object3D} from 'three/src/core/Object3D'; import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig'; import {InputCloneMode} from '../../poly/InputCloneMode'; import {CoreGroup} from '../../../core/geometry/Group'; import {BufferGeometry} from 'three/src/core/BufferGeometry'; import {Mesh} from 'three/src/objects/Mesh'; class BlendSopParamsConfig extends NodeParamsConfig { /** @param name of the attribute to blend */ attribName = ParamConfig.STRING('position'); /** @param blend value. 0 means the result will equal the left input, 1 will equal the right input, and 0.5 will be an average of both. */ blend = ParamConfig.FLOAT(0.5, { range: [0, 1], rangeLocked: [true, true], }); } const ParamsConfig = new BlendSopParamsConfig(); export class BlendSopNode extends TypedSopNode<BlendSopParamsConfig> { params_config = ParamsConfig; static type() { return 'blend'; } static displayedInputNames(): string[] { return ['geometry to blend from', 'geometry to blend to']; } initializeNode() { this.io.inputs.setCount(2); this.io.inputs.initInputsClonedState([InputCloneMode.FROM_NODE, InputCloneMode.NEVER]); } cook(input_contents: CoreGroup[]) { // this.request_input_container 0, (container0)=> // if container0? && (group0 = container0.group())? // this.request_input_container 1, (container1)=> // if container1? && (group1 = container1.group({clone: false}))? //this.eval_all_params => // const container0 = input_containers[0]; // const container1 = input_containers[1]; // const group0 = container0.group(); // const group1 = container1.group(); const core_group0 = input_contents[0]; const core_group1 = input_contents[1]; const objects0 = core_group0.objects(); const objects1 = core_group1.objects(); let object0, object1; for (let i = 0; i < objects0.length; i++) { object0 = objects0[i]; object1 = objects1[i]; this.blend(object0, object1, this.pv.blend); } this.setCoreGroup(core_group0); } // else // this.set_error("input 1 required") // else // this.set_error("input 0 required") private blend(object0: Object3D, object1: Object3D, blend: number) { const geometry0 = (object0 as Mesh).geometry as BufferGeometry; const geometry1 = (object1 as Mesh).geometry as BufferGeometry; if (geometry0 == null || geometry1 == null) { return; } const attrib0 = geometry0.getAttribute(this.pv.attribName); const attrib1 = geometry1.getAttribute(this.pv.attribName); if (attrib0 == null || attrib1 == null) { return; } const attrib0_array = attrib0.array as number[]; const attrib1_array = attrib1.array as number[]; let c0, c1; for (let i = 0; i < attrib0_array.length; i++) { c0 = attrib0_array[i]; c1 = attrib1_array[i]; if (c1 != null) { attrib0_array[i] = (1 - blend) * c0 + blend * c1; } } geometry0.computeVertexNormals(); } }