UNPKG

polygonjs-engine

Version:

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

139 lines (138 loc) 4.53 kB
import {TypedSopNode} from "./_Base"; import {InputCloneMode as InputCloneMode2} from "../../poly/InputCloneMode"; import {Attribute as Attribute2} from "../../../core/geometry/Attribute"; import {CoreGeometry} from "../../../core/geometry/Geometry"; import {NodeParamsConfig, ParamConfig} from "../utils/params/ParamsConfig"; class NormalsSopParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); this.edit = ParamConfig.BOOLEAN(0); this.updateX = ParamConfig.BOOLEAN(0, { visibleIf: {edit: 1} }); this.x = ParamConfig.FLOAT("@N.x", { visibleIf: {updateX: 1, edit: 1}, expression: {forEntities: true} }); this.updateY = ParamConfig.BOOLEAN(0, { visibleIf: {edit: 1} }); this.y = ParamConfig.FLOAT("@N.y", { visibleIf: {updateY: 1, edit: 1}, expression: {forEntities: true} }); this.updateZ = ParamConfig.BOOLEAN(0, { visibleIf: {edit: 1} }); this.z = ParamConfig.FLOAT("@N.z", { visibleIf: {updateZ: 1, edit: 1}, expression: {forEntities: true} }); this.recompute = ParamConfig.BOOLEAN(1, { visibleIf: {edit: 0} }); this.invert = ParamConfig.BOOLEAN(0); } } const ParamsConfig2 = new NormalsSopParamsConfig(); export class NormalsSopNode extends TypedSopNode { constructor() { super(...arguments); this.params_config = ParamsConfig2; } static type() { return "normals"; } static displayedInputNames() { return ["geometry to update normals of"]; } initializeNode() { this.io.inputs.setCount(1); this.io.inputs.initInputsClonedState(InputCloneMode2.FROM_NODE); } async cook(input_contents) { const core_group = input_contents[0]; if (this.pv.edit) { await this._eval_expressions_for_core_group(core_group); } else { if (this.pv.recompute) { core_group.computeVertexNormals(); } } if (this.pv.invert) { this._invert_normals(core_group); } this.setCoreGroup(core_group); } async _eval_expressions_for_core_group(core_group) { const core_objects = core_group.coreObjects(); for (let i = 0; i < core_objects.length; i++) { await this._eval_expressions_for_core_object(core_objects[i]); } } async _eval_expressions_for_core_object(core_object) { const object = core_object.object(); const geometry = object.geometry; const points = core_object.points(); let attrib = geometry.getAttribute(Attribute2.NORMAL); if (!attrib) { const core_geometry = new CoreGeometry(geometry); core_geometry.addNumericAttrib(Attribute2.NORMAL, 3, 0); attrib = geometry.getAttribute(Attribute2.NORMAL); } const array = attrib.array; if (this.pv.updateX) { if (this.p.x.has_expression() && this.p.x.expression_controller) { await this.p.x.expression_controller.compute_expression_for_points(points, (point, value) => { array[point.index() * 3 + 0] = value; }); } else { let point; for (let i = 0; i < points.length; i++) { point = points[i]; array[point.index() * 3 + 0] = this.pv.x; } } } if (this.pv.updateY) { if (this.p.y.has_expression() && this.p.y.expression_controller) { await this.p.y.expression_controller.compute_expression_for_points(points, (point, value) => { array[point.index() * 3 + 1] = value; }); } else { let point; for (let i = 0; i < points.length; i++) { point = points[i]; array[point.index() * 3 + 1] = this.pv.y; } } } if (this.pv.updateZ) { if (this.p.z.has_expression() && this.p.z.expression_controller) { await this.p.z.expression_controller.compute_expression_for_points(points, (point, value) => { array[point.index() * 3 + 2] = value; }); } else { let point; for (let i = 0; i < points.length; i++) { point = points[i]; array[point.index() * 3 + 2] = this.pv.z; } } } } _invert_normals(core_group) { for (let core_object of core_group.coreObjects()) { const geometry = core_object.coreGeometry()?.geometry(); if (geometry) { const normal_attrib = geometry.attributes[Attribute2.NORMAL]; if (normal_attrib) { const array = normal_attrib.array; for (let i = 0; i < array.length; i++) { array[i] *= -1; } } } } } }