UNPKG

polygonjs-engine

Version:

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

157 lines (156 loc) 5.67 kB
import {Vector3 as Vector32} from "three/src/math/Vector3"; import {BufferAttribute as BufferAttribute2} from "three/src/core/BufferAttribute"; import {TypedSopNode} from "./_Base"; import {InputCloneMode as InputCloneMode2} from "../../poly/InputCloneMode"; import {NodeParamsConfig, ParamConfig} from "../utils/params/ParamsConfig"; import {ArrayUtils as ArrayUtils2} from "../../../core/ArrayUtils"; class FaceSopParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); this.makeFacesUnique = ParamConfig.BOOLEAN(0); this.addFaceCenterAttribute = ParamConfig.BOOLEAN(0, { visibleIf: {makeFacesUnique: 1} }); this.addFaceId = ParamConfig.BOOLEAN(0, { visibleIf: {makeFacesUnique: 1} }); this.transform = ParamConfig.BOOLEAN(0, { visibleIf: {makeFacesUnique: 1} }); this.scale = ParamConfig.FLOAT(1, { visibleIf: {makeFacesUnique: 1, transform: 1} }); } } const ParamsConfig2 = new FaceSopParamsConfig(); export class FaceSopNode extends TypedSopNode { constructor() { super(...arguments); this.params_config = ParamsConfig2; } static type() { return "face"; } initializeNode() { this.io.inputs.setCount(1); this.io.inputs.initInputsClonedState(InputCloneMode2.FROM_NODE); } cook(input_contents) { const core_group = input_contents[0]; if (this.pv.makeFacesUnique) { this._makeFacesUnique(core_group); if (this.pv.addFaceCenterAttribute) { this._addFaceCenterAttribute(core_group); } if (this.pv.addFaceId) { this._addFaceId(core_group); } if (this.pv.transform) { this._transform_faces(core_group); } } this.setCoreGroup(core_group); } _makeFacesUnique(core_group) { for (let object of core_group.objects()) { if (object.isMesh) { const geometry = object.geometry; const faces = ArrayUtils2.chunk(geometry.index?.array || [], 3); const points_count = faces.length * 3; for (let attrib_name of Object.keys(geometry.attributes)) { const attrib = geometry.attributes[attrib_name]; const attrib_size = attrib.itemSize; const new_values = new Float32Array(points_count * attrib_size); let new_value_index = 0; faces.forEach((face) => { face.forEach((index) => { for (let i = 0; i < attrib_size; i++) { const current_value = attrib.array[index * attrib_size + i]; new_values[new_value_index] = current_value; new_value_index += 1; } }); }); geometry.setAttribute(attrib_name, new BufferAttribute2(new_values, attrib_size)); } const new_indices = ArrayUtils2.range(points_count); geometry.setIndex(new_indices); } } } _addFaceCenterAttribute(core_group) { const attrib_name = "face_center"; const face_center = new Vector32(); let faces, face, points, point; core_group.coreObjects().forEach((core_object) => { const object = core_object.object(); const core_geometry = core_object.coreGeometry(); if (object.isMesh && core_geometry) { faces = core_geometry.faces(); if (!core_geometry.hasAttrib(attrib_name)) { core_geometry.addNumericAttrib(attrib_name, 3, -1); } for (let fi = 0; fi < faces.length; fi++) { face = faces[fi]; face.center(face_center); points = face.points(); for (let pi = 0; pi < points.length; pi++) { point = points[pi]; point.setAttribValue(attrib_name, face_center); } } } }); } _addFaceId(core_group) { const attrib_name = "face_id"; core_group.coreObjects().forEach((core_object) => { const object = core_object.object(); const core_geometry = core_object.coreGeometry(); if (object.isMesh && core_geometry) { const faces = core_geometry.faces(); if (!core_geometry.hasAttrib(attrib_name)) { core_geometry.addNumericAttrib(attrib_name, 1, -1); } for (let i = 0; i < faces.length; i++) { const face = faces[i]; const points = face.points(); for (let j = 0; j < points.length; j++) { const point = points[j]; point.setAttribValue(attrib_name, i); } } } }); } _transform_faces(core_group) { const attrib_name = "position"; const face_center = new Vector32(); const new_position = new Vector32(); const scale = this.pv.scale; let faces, face, points, point; core_group.coreObjects().forEach((core_object) => { const object = core_object.object(); const core_geometry = core_object.coreGeometry(); if (object.isMesh && core_geometry) { faces = core_geometry.faces(); if (!core_geometry.hasAttrib(attrib_name)) { core_geometry.addNumericAttrib(attrib_name, 3, -1); } for (let fi = 0; fi < faces.length; fi++) { face = faces[fi]; face.center(face_center); points = face.points(); for (let pi = 0; pi < points.length; pi++) { point = points[pi]; const position = point.position(); new_position.x = position.x * scale + face_center.x * (1 - scale); new_position.y = position.y * scale + face_center.y * (1 - scale); new_position.z = position.z * scale + face_center.z * (1 - scale); point.setAttribValue(attrib_name, new_position); } } } }); } }